<template>
  <div class="asset-tags">
    <div ref="container" class="tag-container">
      <div
        v-for="(child, i) in tags"
        :key="i"
        class="tag main-tag"
        :class="{ hide: i >= showNum }"
      >
        <span @click="tagClick(child.tag)">{{ child.tag }}</span>
        <el-icon
            v-if="child.modifiable"
            class="tag-close el-icon-close"
            @click="delTag(child.tag, i)"
        >
          <Close />
        </el-icon>
      </div>

      <el-popover
        v-if="showNum < tags.length"
        placement="bottom"
        :append-to-body="false"
        trigger="hover"
      >
        <div class="tag-container pop-container">
          <div
            v-for="(pop_tag, pop_i) in tags.slice(showNum)"
            :key="`pop_${pop_i}`"
            class="tag"
          >
            <span>{{ pop_tag.tag }}</span>
            <i
              v-if="pop_tag.modifiable"
              class="tag-close el-icon-close"
              @click="delTag(pop_tag.tag, pop_i)"
            ></i>
          </div>
        </div>
        <div slot="reference" class="tag tag-num">
          <span>({{ tags.length - showNum }})</span>
        </div>
      </el-popover>
      <div v-if="!disabled && tags.length < maxTagLength" class="new-container">
        <el-autocomplete
          v-if="inputVisible"
          ref="saveTagInput"
          v-model.trim="inputValue"
          class="new-tag-input"
          :popper-append-to-body="false"
          :fetch-suggestions="querySearch"
          :maxlength="maxTextLength"
          @blur="cancelInput"
          @input="changeInput"
          @select="selectInput"
          @keyup.enter.native="inputConfirm"
        >
          <template #suffix>
            <el-icon @click="inputConfirm" class="el-input__icon">
              <check />
            </el-icon>
          </template>
        </el-autocomplete>
        <div v-else class="new-tag" @click="showInput">+ 新增标签</div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ElMessage } from 'element-plus';
import {defineProps,defineEmits,ref,watch,onBeforeUnmount,inject,nextTick} from 'vue';
import {useStore} from 'vuex';
const store =useStore();
  const aggregation = inject<any | null>('aggregation', null);  
  const emit=defineEmits(['tagClick','updateTags','input'])
  const props=defineProps({
    value: {
      default: () => [],
    },
    disabled: {
      // 是否禁用
      type: Boolean,
      default: false,
    },
    maxTagLength: {
      // 最多输入多少个标签
      type: Number,
      default: 999,
    },
    maxTextLength: {
      // 标签最大输入文本数
      type: Number,
      default: 20,
    },
    colNum: {
      // 允许展示的行数 0 为不限制
      type: Number,
      default: 0,
    },
    id: {
      // 资产id
      type: String,
      default: '',
    },
    category: {
      type: String,
      default: '',
    },
    isBatch: {
      // 是否批量操作
      type: Boolean,
      default: false,
    },
  })
  const saveTagInput=ref<any>(null)
  const tags=ref<any>([]);
  const container =ref(null)
  const queryTags=ref([]);
  const inputVisible=ref(false);
  const inputValue=ref('');
  const showNum=ref<any>(99);
  const timer=ref<any>(null);
  watch(()=>props.value,(newVal)=>{
    if (newVal instanceof Array) {
          tags.value = newVal
        } else {
          tags.value = []
        }
  },
  {
    immediate: true,
    deep: true,
  }
  )  
  watch(()=>tags.value,()=>{
    showNum.value = 99
        if (props.colNum === 0) return
        nextTick(() => {
          let showNums = 0
          const containers:any = container.value // 获取存放容器
          const containerWidth = containers.clientWidth // 容器宽度
          const children = [...containers.querySelectorAll('.main-tag')]
          let usedWidth = 0 // 使用宽度
          let usedCol = 1 // 已使用行数
          const allowWidth = children.length >= props.maxTagLength ? 50 : 200 // 预留宽度
          // 遍历子节点如果长度大于容器规定长度则整合后面的标签
          for (let i = 0; i < children.length; i++) {
            const curWidth = children[i].offsetWidth + 8 // 当前标签占用宽度
            // 当前子节点展示后在容器范围内
            if (usedWidth + curWidth < containerWidth) {
              if (usedCol < props.colNum) {
                // 当前列不是最后一列展示标签
                showNums++
                usedWidth += curWidth
              } else {
                // 当前列是最后一列 计算预留空间
                if (usedWidth + curWidth < containerWidth - allowWidth) {
                  showNums++
                  usedWidth += curWidth
                } else {
                  break
                }
              }
            }
            // 当前子节点展示后超出容器范围
            else {
              // 非最后一行  重置使用宽度 使用行数加一
              if (usedCol < props.colNum) {
                usedCol++
                showNums++
                usedWidth = curWidth
              } else {
                break
              }
            }
          }
          showNum.value = showNum
        })
  })
  onBeforeUnmount(() => {
  clearTimeout(timer.value);
});
 const tagClick=(val)=> {
      emit('tagClick', val)
    }
   const showInput=()=> {
      inputVisible.value = true
      nextTick(() => {
           saveTagInput.value.focus(); 
      })
    }
  const inputConfirm = async () => {
  const inputValues = inputValue.value;
  if (tags.value.some((el) => el.tag === inputValues)) {
    return ElMessage.error('输入标签已存在');
  }
  if (!inputValues) return;
  if (props.isBatch) {
    tags.value.push({
      tag: inputValue.value,
      modifiable: true,
    });
    inputVisible.value = false;
    inputValue.value = '';
    updateValue(tags.value);
    return;
  }
  const { code, data } = await store.dispatch('attack/appendTagsV2', {
    assets: [
      {
        assetId: props.id,
        category: props.category,
      },
    ],
    tags: [inputValues],
  });
  if (code === 0) {
    tags.value.push({
      tag: inputValues,
      modifiable: true,
    });
    inputVisible.value = false;
    inputValue.value = '';
    setTimeout(() => {
      emit('updateTags');
    }, 2000);
  }
};
   const cancelInput=()=> {
      setTimeout(() => {
        if (!inputValue.value) {
          inputVisible.value = false
        }
      }, 222)
    }
   const changeInput=(v)=> {
      inputValue.value =inputValue.value.replace(/,/g, '')
    }
   const selectInput=(item)=> {
      inputValue.value = item.tag
    }
    // 模糊匹配
    const querySearch=async(queryString, cb)=> {
      const { code, data } = await store.dispatch('expose/queryTagList', {
        tag: queryString,
        pageNumber: 1,
        pageSize: 1000,
      })
      if (code === 0) {
        const results = data.list
        results.forEach((el) => {
          el.value = tags.value.map((item) => item.tag).includes(el.tag)
            ? el.tag + '（已添加）'
            : el.tag
        })
        cb(results)
      }
    }
    // 删除标签
    const delTag=async(tag, i)=> {
      const tagss =tags.value.filter((el) => el.tag !== tag)
      if (props.isBatch) {
        tags.value = tagss
        updateValue(tags.value)
        return
      }
      const { code, data } = await store.dispatch('api/deleteTags', {
        exposedCode: props.category,
        assetId: props.id,
        tag,
      })
      if (code === 0) {
        ElMessage.success('正在删除')
        tags.value = tagss
        setTimeout(() => {
          emit('updateTags')
        }, 2000)
      }
    }
  const updateValue=(v)=> {
      emit('input', v)
    }
</script>
<style lang="scss" scoped>
.asset-tags {
  // display: flex;
  // background: #242731;
  .tag-container {
    // flex: 1;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    // width: 0;
    .tag {
      flex: 0 0 auto;
      display: flex;
      align-items: center;
      height: 26px;
      box-sizing: border-box;
      padding: 0 12px;
      margin-bottom: 12px;
      font-family: PingFang SC;
      font-size: 12px;
      font-weight: normal;
      letter-spacing: 0em;
      line-height: 12px;
      color: #3aceff;
      border: 0.5px solid rgba(58, 206, 255, 0.6);
      border-radius: 4px;
      background: rgba(58, 206, 255, 0.1);
      &:hover:not(.tag-num) {
        // padding: 0 6px;
        background: rgba(58, 206, 255, 0.3);
        .tag-close {
          display: inherit;
        }
      }
      &.tag-num {
        max-width: 50px;
        margin-right: 10px !important;
        &:hover {
          background: rgba(58, 206, 255, 0.3);
        }
      }
      &:not(:last-of-type) {
        margin-right: 10px;
      }
      > span {
        cursor: pointer;
      }
      .tag-close {
        width: 12px;
        margin-left: 4px;
        display: none;
        cursor: pointer;
      }
    }
  }
  .new-container {
    // margin-left: 8px;
    margin-bottom: 12px;
    line-height: 14px;
    flex: 0 0 auto;
    .new-tag {
      display: flex;
      align-items: center;
      height: 26px;
      box-sizing: border-box;
      padding: 0 10px;
      font-family: PingFang SC;
      font-size: 12px;
      font-weight: normal;
      letter-spacing: 0em;
      line-height: 12px;
      color: $-v-color-primary;
      background: rgba(58, 125, 255, 0.1);
      border: 0.5px dashed $-v-color-primary;
      border-radius: 4px;
      cursor: pointer;
      &:hover {
        box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.3);
      }
    }
    &::v-deep .el-input__wrapper {
      width: 150px;
      height: 26px;
      font-size: 12px;
      border-radius: 13px;
      background: transparent;
      //border: 1px solid $-v-color-primary;

    }
    &::v-deep .el-input__icon {
      line-height: 26px;

      cursor: pointer;
      &:hover {
        color: $-v-color-primary;
      }
    }

  }
  .pop-container {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    width: inherit;
    max-width: 360px;
    max-height: 200px;
    padding: 12px;
    overflow-y: auto;

  }


}

.hide {
  display: none !important;
}
</style>
